from llmtcg.agents.base import Agent
from llmtcg.agents.testers.base import TestSceneGeneratingAgent
from llmtcg.chat.model import ChatContext

from loguru import logger

from dataclasses import dataclass, field
from typing import List, Tuple
from tempfile import mkstemp
from subprocess import run, PIPE, CompletedProcess
from os import path


@dataclass
class LinuxSyscallTesterAgent(TestSceneGeneratingAgent):

    @property
    def system_prompt(self) -> str:
        custom_system_prompt = """
        You are supposed to generate as many test scenes as possible. Particularly, you
        should take care with different error flags. These flags should be reported
        properly.
        """
        return super(LinuxSyscallTesterAgent, self).system_prompt + custom_system_prompt

    def get_all_supported_syscalls(self) -> List[str]:
        proc = run("man syscalls", stdin=PIPE, stdout=PIPE, stderr=PIPE, shell=True, check=True)
        stdout = proc.stdout.decode()
        ctx = ChatContext(self.chat_model, "LinuxSyscallTesterAgent::getAllSupportedSyscalls")
        resp = ctx.chat(f"""
        Here is the result of `man syscalls` in the current system:

        ```
        {stdout}
        ```

        Please list all the syscall names supported according to the manpage above.
        Each syscall name should take a line, and formatted as "syscall::<syscall_name>".
        """)

        syscall_names = []
        for line in resp.splitlines():
            line = line.strip()
            if line.startswith("syscall::"):
                syscall_name = line.split("::")[1]
                syscall_names.append(syscall_name)

        if len(syscall_names) == 0:
            logger.debug(resp)
            raise Exception("no syscalls found")

        return syscall_names
